package api;

import com.fasterxml.jackson.databind.ObjectMapper;
import model.User;
import model.UserDao;

import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import java.io.IOException;

/**
 * Created with IntelliJ IDEA.
 * Description:
 * User: 言初
 * Date: 2024-04-11
 * Time: 11:26
 */

@WebServlet("/login")

// 登录页面的前后端交互  ： 后端代码的编写


public class LoginServlet extends HttpServlet {

    private ObjectMapper objectMapper = new ObjectMapper();// 把数据转成json格式


    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        // 1. 从请求中 获得 用户名和密码
        // 如果前端拿到的 用户名是 中文，那么后端 这里拿到的用户名可能是  乱码
        // 所以我们需要明显告诉  servlet 服务器  我们要使用什么编码方式来解析 数据(请求)
        req.setCharacterEncoding("utf8"); // 指定解码方式

        String username = req.getParameter("username");
        String password = req.getParameter("password");

        // 2.判断拿到的数据，是不是空数据什么的
        if(username==null || username.equals("null") || password==null || password.equals("null")){
            // 用户名密码残缺的情况，必然 登录失败
            String html = "<h3>缺少用户名或密码，登录失败</h3>";
            resp.setContentType("text/html; charset=utf8"); // 返回的响应的数据类型
            resp.getWriter().write(html);
            return;
        }

        // 走到这里，表示这2个参数都存在，
        // 读取数据库，看看 用户名和密码 是否和数据库中的数据匹配
        UserDao userDao = new UserDao();
        // 先去数据库中 按照用户名来找一个 看看 是否存在这样的 对象
        User user = userDao.selectByName(username);

        // 但是实际的网站，不会具体说明是 用户名错了，还是密码错了，都会说 用户名或密码错误
        if(user==null){
            // System.out.println("用户不存在");
            // 用户名不存在
            String html = "<h3>用户名或密码错误</h3>";
            resp.setContentType("text/html; charset=utf8");
            resp.getWriter().write(html);
            return;
        }
        // 然后 对照 密码是否正确
        if(!password.equals(user.getPassword())){
            // 密码错误
            String html = "<h3>用户名或密码错误</h3>";
            resp.setContentType("text/html; charset=utf8");
            resp.getWriter().write(html);
            return;
        }


        // 3. 用户名 密码都正确 ，登录成功
        // 登录成功，需要设置会话 (让服务器保存当前用户的一些数据,下次再用的时候，用户立刻就能获取到)
        // 会话 类似于 就诊卡中 所存储的我们的信息
        // 会话 可以理解成一个哈希表
        // 每个客户端都会对应到 表里面的 一个键值对
        // 键是 一个字符串：sessionId （是唯一的）
        // 值是 HttpSession 对象：这个对象也可以按照 键值对的方式 来 存储数据
        // HttpSession 对象 使用 getAttribute 和 setAttribute 来获取或者设置其他的键值对
        // 会话和HttpSession 对象 就是像 键值对 又套了一层键值对

        // 创建会话
        HttpSession session = req.getSession(true);
        // 把 用户信息对象 存储到 session 中,下次用户访问其他页面，就可以直接拿到 会话，进一步拿到之前的 User 对象了
        session.setAttribute("user",user);


        // 4. 返回一个 重定向 响应 让它可以跳转到 博客 列表页
        resp.sendRedirect("blog_list.html");


    }


    // 通过这个方法来 判定 用户的登录状态 ：
    // 已登录：返回 200 (正常情况下)
    // 未登录：返回 403 (没有权限的意思)
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {

        // 看当前请求是否 已经存在 并且 当前会话包含User对象
        // 查询会话是否存在
        HttpSession session = req.getSession(false);
        if(session==null){
            // 会话不存在(未登录状态)
            resp.setStatus(403);
            return;
        }

        // 会话存在
        // 查询 会话 中是否存在 User对象
        User user = (User) session.getAttribute("user");

        if(user==null){
            // 会话对象存在 ，User对象 不存在 ，用户未登录状态
            resp.setStatus(403);
            return;
        }

        // 用户是登录状态
        // 200 是默认的状态码，你不写这一句也会返回200
        resp.setStatus(200);



        // 把获取到的 登录用户信息通过响应返回回去
        resp.setContentType("application/json; charset=utf8");

        // 把整体的这个User 对象给它返回回去
        // 把登录用户的信息返回回去
        user.setPassword(""); // 避免把密码也返回给前端，避免秘密的泄露
        String respJson = objectMapper.writeValueAsString(user);
        resp.getWriter().write(respJson);

    }
}








